<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>jdbc学习笔记 | zylai</title><meta name="keywords" content="mysql"><meta name="author" content="zylai"><meta name="copyright" content="zylai"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="1 简介和基础使用 1.1 简介 JDBC：是sun发布的一个java程序和数据库之间通信的规范（接口） 各大数据库厂商去实现JDBC规范（实现类），将这些实现类打成压缩包，就是所谓的jar包 比如：  1.2 创建连接 url：防止中文乱码，加上参数useUnicode&#x3D;true&amp;characterEncoding&#x3D;utf-8。url的标准格式为：jdbc:mysql:&#x2F;&#x2F;ip:端口号&#x2F;">
<meta property="og:type" content="article">
<meta property="og:title" content="jdbc学习笔记">
<meta property="og:url" content="https://zhaoyunlai.gitee.io/posts/4bf3ee607b9f/index.html">
<meta property="og:site_name" content="zylai">
<meta property="og:description" content="1 简介和基础使用 1.1 简介 JDBC：是sun发布的一个java程序和数据库之间通信的规范（接口） 各大数据库厂商去实现JDBC规范（实现类），将这些实现类打成压缩包，就是所谓的jar包 比如：  1.2 创建连接 url：防止中文乱码，加上参数useUnicode&#x3D;true&amp;characterEncoding&#x3D;utf-8。url的标准格式为：jdbc:mysql:&#x2F;&#x2F;ip:端口号&#x2F;">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/jdbcBack.webp">
<meta property="article:published_time" content="2022-06-22T11:57:26.000Z">
<meta property="article:modified_time" content="2022-08-03T12:18:53.796Z">
<meta property="article:author" content="zylai">
<meta property="article:tag" content="mysql">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/jdbcBack.webp"><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="https://zhaoyunlai.gitee.io/posts/4bf3ee607b9f/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//hm.baidu.com"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.min.css" media="print" onload="this.media='all'"><script>var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?ec7714e43e379e663d7258bb72abd0cc";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/search.xml","preload":false,"languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'jdbc学习笔记',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-08-03 20:18:53'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><!-- hexo injector head_end start --><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Zfour/hexo-electric-clock@1.0.6/clock.css"><!-- hexo injector head_end end --><meta name="generator" content="Hexo 5.4.2"></head><body><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="/img/avatar.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">18</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">14</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">11</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/jdbcBack.webp')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">zylai</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">jdbc学习笔记</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2022-06-22T11:57:26.000Z" title="发表于 2022-06-22 19:57:26">2022-06-22</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-08-03T12:18:53.796Z" title="更新于 2022-08-03 20:18:53">2022-08-03</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/javaSE/">javaSE</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="jdbc学习笔记"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h2 id="1-简介和基础使用">1 简介和基础使用</h2>
<h3 id="1-1-简介">1.1 简介</h3>
<p>JDBC：是sun发布的一个java程序和数据库之间通信的规范（接口）</p>
<p>各大数据库厂商去实现JDBC规范（实现类），将这些实现类打成压缩包，就是所谓的jar包</p>
<p>比如：</p>
<p><img src="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/image-20220621124839866.png" alt="image-20220621124839866"></p>
<h3 id="1-2-创建连接">1.2 创建连接</h3>
<p>url：防止中文乱码，加上参数<code>useUnicode=true&amp;characterEncoding=utf-8</code>。url的标准格式为：<code>jdbc:mysql://ip:端口号/数据库名称?参数列表</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo01</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> ClassNotFoundException, SQLException &#123;</span><br><span class="line"><span class="comment">//        1.添加jar包</span></span><br><span class="line"><span class="comment">//        2.加载驱动</span></span><br><span class="line">       Class.forName(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>);</span><br><span class="line"><span class="comment">//       3.通过驱动管理器获取连接对象</span></span><br><span class="line"><span class="comment">//        3-1 准备url</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">url</span> <span class="operator">=</span> <span class="string">&quot;jdbc:mysql://localhost:3306/fruitdb&quot;</span>;</span><br><span class="line"><span class="comment">//        3-2 准备用户名</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">usr</span> <span class="operator">=</span> <span class="string">&quot;root&quot;</span>;</span><br><span class="line"><span class="comment">//        3-3 准备密码</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">pwd</span> <span class="operator">=</span> <span class="string">&quot;root&quot;</span>;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> DriverManager.getConnection(url,usr,pwd);</span><br><span class="line">        System.out.println(<span class="string">&quot;conn = &quot;</span>+connection);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="1-3-添加数据">1.3 添加数据</h3>
<p>先建立连接之后，得到connection对象，这个对象相当于建立了一条连接数据库和java之间的马路，通过connection对象得到预处理对象<code>PreparedStatement</code>，这个对象相当于马路上的一辆车，用于运送真实的数据。</p>
<p>在SQL语句中，使用<code>?</code>当做占位符，再通过预处理对象的set方法为占位符填充内容</p>
<p>最后，记得关闭连接，先关闭预处理对象，再关闭连接对象</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo02</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> ClassNotFoundException, SQLException &#123;</span><br><span class="line"><span class="comment">//        1.加载驱动</span></span><br><span class="line">        Class.forName(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>);</span><br><span class="line">        <span class="comment">//       2.通过驱动管理器获取连接对象</span></span><br><span class="line"><span class="comment">//        2-1 准备url</span></span><br><span class="line"><span class="comment">//        url表示和数据库通信的地址，如果需要带参数，则需要使用？进行连接</span></span><br><span class="line"><span class="comment">//        如果使用多个参数,多个参数之间使用&amp;连接</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">url</span> <span class="operator">=</span> <span class="string">&quot;jdbc:mysql://localhost:3306/fruitdb?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8&quot;</span>;</span><br><span class="line"><span class="comment">//        2-2 准备用户名</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">usr</span> <span class="operator">=</span> <span class="string">&quot;root&quot;</span>;</span><br><span class="line"><span class="comment">//        2-3 准备密码</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">pwd</span> <span class="operator">=</span> <span class="string">&quot;root&quot;</span>;</span><br><span class="line">        </span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> DriverManager.getConnection(url,usr,pwd);</span><br><span class="line"></span><br><span class="line"><span class="comment">//        3. 编写SQL语句</span></span><br><span class="line"><span class="comment">//        id，fname,price,fcount,remark</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;insert into t_fruit value(0,?,?,?,?)&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//        4.创建预处理对象</span></span><br><span class="line">        <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> connection.prepareStatement(sql);</span><br><span class="line"><span class="comment">//        5.填充参数</span></span><br><span class="line">        psmt.setString(<span class="number">1</span>,<span class="string">&quot;榴莲&quot;</span>);</span><br><span class="line">        psmt.setInt(<span class="number">2</span>,<span class="number">15</span>);</span><br><span class="line">        psmt.setInt(<span class="number">3</span>,<span class="number">100</span>);</span><br><span class="line">        psmt.setString(<span class="number">4</span>,<span class="string">&quot;榴莲是一种神奇的水果&quot;</span>);</span><br><span class="line"><span class="comment">//        6.执行更新（增删改），返回影响行数</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> psmt.executeUpdate();</span><br><span class="line">        System.out.println(i&gt;<span class="number">0</span>?<span class="string">&quot;添加成功！&quot;</span>:<span class="string">&quot;添加失败&quot;</span>);</span><br><span class="line"><span class="comment">//        7.释放资源</span></span><br><span class="line">        psmt.close();</span><br><span class="line">        connection.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="1-4-更新和删除数据">1.4 更新和删除数据</h3>
<p>和添加数据步骤都一样，最后都是预处理对象调用<code>executeUpdate</code>方法并返回影响行数。因此更新与修改和添加的不同就是SQL语句和预处理设置SQL中的占位符的值而已。</p>
<p>更新：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">Fruit</span> <span class="variable">fruit</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Fruit</span>(<span class="number">33</span>, <span class="string">&quot;猕猴桃&quot;</span>, <span class="string">&quot;猕猴桃啊猕猴桃&quot;</span>);</span><br><span class="line"></span><br><span class="line">       Class.forName(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>);</span><br><span class="line">       <span class="type">String</span> <span class="variable">url</span> <span class="operator">=</span> <span class="string">&quot;jdbc:mysql://localhost:3306/fruitdb?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf8&quot;</span>;</span><br><span class="line">       <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> DriverManager.getConnection(url, <span class="string">&quot;root&quot;</span>, <span class="string">&quot;root&quot;</span>);</span><br><span class="line"></span><br><span class="line">       <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;update t_fruit set fname=?,remark = ? where fid = ?&quot;</span>;</span><br><span class="line">       <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> connection.prepareStatement(sql);</span><br><span class="line">       psmt.setString(<span class="number">1</span>, fruit.getFname());</span><br><span class="line">       psmt.setString(<span class="number">2</span>, fruit.getRemark());</span><br><span class="line">       psmt.setInt(<span class="number">3</span>,fruit.getFid());</span><br><span class="line">       <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> psmt.executeUpdate();</span><br><span class="line">       System.out.println(i&gt;<span class="number">0</span>?<span class="string">&quot;修改成功&quot;</span>:<span class="string">&quot;修改失败&quot;</span>);</span><br><span class="line"></span><br><span class="line">       psmt.close();</span><br><span class="line">       connection.close();</span><br></pre></td></tr></table></figure>
<p>删除：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">Class.forName(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>);</span><br><span class="line">      <span class="type">String</span> <span class="variable">url</span> <span class="operator">=</span> <span class="string">&quot;jdbc:mysql://localhost:3306/fruitdb?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf8&quot;</span>;</span><br><span class="line">      <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> DriverManager.getConnection(url, <span class="string">&quot;root&quot;</span>, <span class="string">&quot;root&quot;</span>);</span><br><span class="line"></span><br><span class="line">      <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;delete from t_fruit where fid = ?&quot;</span>;</span><br><span class="line">      <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> connection.prepareStatement(sql);</span><br><span class="line">      psmt.setInt(<span class="number">1</span>,<span class="number">33</span>);</span><br><span class="line"></span><br><span class="line">      <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> psmt.executeUpdate();</span><br><span class="line">      System.out.println(i&gt;<span class="number">0</span>?<span class="string">&quot;删除成功&quot;</span>:<span class="string">&quot;删除失败&quot;</span>);</span><br><span class="line"></span><br><span class="line">      psmt.close();</span><br><span class="line">      connection.close();</span><br></pre></td></tr></table></figure>
<h3 id="1-5-增删更新总结">1.5 增删更新总结</h3>
<h4 id="1-5-1-步骤：">1.5.1 步骤：</h4>
<ol>
<li>加载驱动</li>
<li>通过驱动获取连接对象<code>Connection</code>，连接对象相当于连接java与数据库之间的一条马路</li>
<li>编写SQL语句，语句中使用占位符</li>
<li>创建数据预处理对象<code>PreparedStatement</code>，数据预处理对象相当于马路上运送SQL语句的小车</li>
<li>填充预处理数据对象的参数</li>
<li>执行更新参数，对于增删查都是执行<code>PreparedStatement</code>对象的<code>executeUpdate</code>方法，返回影响行数</li>
<li>关闭资源，关闭<code>PreparedStatement</code>对象和<code>Connection</code>对象</li>
</ol>
<h3 id="1-6-查询">1.6 查询</h3>
<p>查询与增删改的不同之处在于：</p>
<ul>
<li>预处理对象执行的是<code>executeQuery</code>方法</li>
<li>方法返回结果集<code>ResultSet</code>，可以遍历结果接进行数据的操作</li>
</ul>
<p>例如：查询所有数据</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//        1.加载驱动</span></span><br><span class="line">        Class.forName(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>);</span><br><span class="line">        <span class="type">String</span> <span class="variable">url</span> <span class="operator">=</span> <span class="string">&quot;jdbc:mysql://localhost:3306/fruitdb?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf8&quot;</span>;</span><br><span class="line"><span class="comment">//        2.获取连接对象</span></span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> DriverManager.getConnection(url, <span class="string">&quot;root&quot;</span>, <span class="string">&quot;root&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//        3.编写SQL语句</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;select * from t_fruit&quot;</span>;</span><br><span class="line"><span class="comment">//        4.创建预处理命令对象</span></span><br><span class="line">        <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> connection.prepareStatement(sql);</span><br><span class="line"><span class="comment">//        5.填充参数，这里没有，略</span></span><br><span class="line"><span class="comment">//        6.执行查询，返回结果集</span></span><br><span class="line">        <span class="type">ResultSet</span> <span class="variable">res</span> <span class="operator">=</span> psmt.executeQuery();</span><br><span class="line">        List&lt;Fruit&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line"><span class="comment">//        7.处理结果集</span></span><br><span class="line"><span class="comment">//        判断下一行是否有数据，并且指针指到下一行</span></span><br><span class="line">        <span class="keyword">while</span>(res.next())&#123;</span><br><span class="line"><span class="comment">//            表示当前行第一列的数据，因为这一列是int类型的数据，所以使用getInt</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">fid</span> <span class="operator">=</span> res.getInt(<span class="number">1</span>);</span><br><span class="line"><span class="comment">//            也可以通过结果集的列名</span></span><br><span class="line">            <span class="type">String</span> <span class="variable">fname</span> <span class="operator">=</span> res.getString(<span class="string">&quot;fname&quot;</span>);</span><br><span class="line">            <span class="type">int</span> <span class="variable">price</span> <span class="operator">=</span> res.getInt(<span class="number">3</span>);</span><br><span class="line">            <span class="type">int</span> <span class="variable">fcount</span> <span class="operator">=</span> res.getInt(<span class="string">&quot;fcount&quot;</span>);</span><br><span class="line">            <span class="type">String</span> <span class="variable">remark</span> <span class="operator">=</span> res.getString(<span class="string">&quot;remark&quot;</span>);</span><br><span class="line"></span><br><span class="line">            <span class="type">Fruit</span> <span class="variable">fruit</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Fruit</span>(fid,fname,price,fcount,remark);</span><br><span class="line">            list.add(fruit);</span><br><span class="line">        &#125;</span><br><span class="line"><span class="comment">//        8.释放资源</span></span><br><span class="line">        res.close();</span><br><span class="line">        psmt.close();</span><br><span class="line">        connection.close();</span><br><span class="line">        <span class="keyword">for</span> (Fruit fruit : list) &#123;</span><br><span class="line">            System.out.println(fruit);</span><br><span class="line">        &#125;</span><br></pre></td></tr></table></figure>
<p>查询指定的一条记录：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">		Class.forName(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>);</span><br><span class="line">        <span class="type">String</span> <span class="variable">url</span> <span class="operator">=</span> <span class="string">&quot;jdbc:mysql://localhost:3306/fruitdb?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf8&quot;</span>;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> DriverManager.getConnection(url, <span class="string">&quot;root&quot;</span>, <span class="string">&quot;root&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//        编写SQL语句</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;select * from t_fruit where fid = ?&quot;</span>;</span><br><span class="line"><span class="comment">//        创建预处理命令对象</span></span><br><span class="line">        <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> connection.prepareStatement(sql);</span><br><span class="line"><span class="comment">//        填充参数</span></span><br><span class="line">        psmt.setInt(<span class="number">1</span>,<span class="number">2</span>);</span><br><span class="line"><span class="comment">//        由于fid是主键，所以可以不使用列表，这里改一下</span></span><br><span class="line"><span class="comment">//        执行查询，返回结果集</span></span><br><span class="line">        <span class="type">ResultSet</span> <span class="variable">res</span> <span class="operator">=</span> psmt.executeQuery();</span><br><span class="line"><span class="comment">//        判断下一行是否有数据，并且指针指到下一行</span></span><br><span class="line">        <span class="keyword">if</span>(res.next())&#123;</span><br><span class="line"><span class="comment">//            表示当前行第一列的数据，因为这一列是int类型的数据，所以使用getInt</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">fid</span> <span class="operator">=</span> res.getInt(<span class="number">1</span>);</span><br><span class="line"><span class="comment">//            也可以通过结果集的列名</span></span><br><span class="line">            <span class="type">String</span> <span class="variable">fname</span> <span class="operator">=</span> res.getString(<span class="string">&quot;fname&quot;</span>);</span><br><span class="line">            <span class="type">int</span> <span class="variable">price</span> <span class="operator">=</span> res.getInt(<span class="number">3</span>);</span><br><span class="line">            <span class="type">int</span> <span class="variable">fcount</span> <span class="operator">=</span> res.getInt(<span class="string">&quot;fcount&quot;</span>);</span><br><span class="line">            <span class="type">String</span> <span class="variable">remark</span> <span class="operator">=</span> res.getString(<span class="string">&quot;remark&quot;</span>);</span><br><span class="line">            <span class="type">Fruit</span> <span class="variable">fruit</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Fruit</span>(fid,fname,price,fcount,remark);</span><br><span class="line">            System.out.println(fruit);</span><br><span class="line">        &#125;</span><br><span class="line"><span class="comment">//        释放资源</span></span><br><span class="line">        res.close();</span><br><span class="line">        psmt.close();</span><br><span class="line">        connection.close();</span><br></pre></td></tr></table></figure>
<p>查询总记录条数：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">        Class.forName(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>);</span><br><span class="line">        <span class="type">String</span> <span class="variable">url</span> <span class="operator">=</span> <span class="string">&quot;jdbc:mysql://localhost:3306/fruitdb?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf8&quot;</span>;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> DriverManager.getConnection(url, <span class="string">&quot;root&quot;</span>, <span class="string">&quot;root&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//        编写SQL语句</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;select count(*) from t_fruit&quot;</span>;</span><br><span class="line"><span class="comment">//        创建预处理命令对象</span></span><br><span class="line">        <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> connection.prepareStatement(sql);</span><br><span class="line"><span class="comment">//        执行查询，返回结果集</span></span><br><span class="line"><span class="comment">//        这里返回的是一个一行一列的数据</span></span><br><span class="line">        <span class="type">ResultSet</span> <span class="variable">res</span> <span class="operator">=</span> psmt.executeQuery();</span><br><span class="line"><span class="comment">//        判断下一行是否有数据，并且指针指到下一行</span></span><br><span class="line">        <span class="keyword">if</span>(res.next())&#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">count</span> <span class="operator">=</span> res.getInt(<span class="number">1</span>);</span><br><span class="line">            System.out.println(<span class="string">&quot;总记录条数：&quot;</span>+count);</span><br><span class="line">        &#125;</span><br><span class="line"><span class="comment">//        释放资源</span></span><br><span class="line">        res.close();</span><br><span class="line">        psmt.close();</span><br><span class="line">        connection.close();</span><br></pre></td></tr></table></figure>
<h3 id="1-7-查询总结">1.7 查询总结</h3>
<h4 id="1-7-1-查询与增删改的不同之处在于：">1.7.1 查询与增删改的不同之处在于：</h4>
<ul>
<li>预处理对象执行的是<code>executeQuery</code>方法</li>
<li>方法返回结果集<code>ResultSet</code>，可以遍历结果接进行数据的操作</li>
</ul>
<h4 id="1-7-2-步骤：">1.7.2 步骤：</h4>
<ol>
<li>加载驱动</li>
<li>通过驱动获取连接对象<code>Connection</code>，连接对象相当于连接java与数据库之间的一条马路</li>
<li>编写SQL语句，语句中使用占位符</li>
<li>创建数据预处理对象<code>PreparedStatement</code>，数据预处理对象相当于马路上运送SQL语句的小车</li>
<li>填充预处理数据对象的参数</li>
<li>执行更新参数，执行<code>executeQuery</code>方法</li>
<li>返回结果集<code>ResultSet</code></li>
<li>关闭资源，关闭<code>ResultSet</code>对象、<code>PreparedStatement</code>对象和<code>Connection</code>对象</li>
</ol>
<h3 id="1-8-批处理">1.8 批处理</h3>
<p>如果一次性添加大量数据，若每一条数据都单独执行一次方法，那么效率很低下，所以可以采用批处理的方法来提高处理的效率。</p>
<p>批处理操作的步骤：</p>
<ol>
<li>如果执行批处理任务，需要在添加一个参数： rewriteBatchedStatements=true</li>
<li>将数据加入一个批次：psmt.addBatch();</li>
<li>执行批处理：int[] batch = psmt.executeBatch();如果继续进行处理，需要进行clear：psmt.clear();</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zylai.jdbc01;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.sql.Connection;</span><br><span class="line"><span class="keyword">import</span> java.sql.DriverManager;</span><br><span class="line"><span class="keyword">import</span> java.sql.PreparedStatement;</span><br><span class="line"><span class="keyword">import</span> java.sql.SQLException;</span><br><span class="line"><span class="keyword">import</span> java.util.Arrays;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Zhao YunLai</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2022/06/21/12:54</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 添加</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">DemoAddBatch</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> ClassNotFoundException, SQLException &#123;</span><br><span class="line"><span class="comment">//        1.加载驱动</span></span><br><span class="line">        Class.forName(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>);</span><br><span class="line">        <span class="comment">//       2.通过驱动管理器获取连接对象</span></span><br><span class="line"><span class="comment">//        批处理操作一</span></span><br><span class="line"><span class="comment">//        如果执行批处理任务，需要添加一个参数： rewriteBatchedStatements=true</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">url</span> <span class="operator">=</span> <span class="string">&quot;jdbc:mysql://localhost:3306/fruitdb?rewriteBatchedStatements=true&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8&quot;</span>;</span><br><span class="line"><span class="comment">//        2-2 准备用户名</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">usr</span> <span class="operator">=</span> <span class="string">&quot;root&quot;</span>;</span><br><span class="line"><span class="comment">//        2-3 准备密码</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">pwd</span> <span class="operator">=</span> <span class="string">&quot;root&quot;</span>;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> DriverManager.getConnection(url,usr,pwd);</span><br><span class="line"><span class="comment">//        3. 编写SQL语句</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;insert into t_fruit value(0,?,?,?,?)&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//        4.创建预处理对象</span></span><br><span class="line">        <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> connection.prepareStatement(sql);</span><br><span class="line"><span class="comment">//        5.填充参数</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">1000</span>; i++) &#123;</span><br><span class="line">            psmt.setString(<span class="number">1</span>,<span class="string">&quot;榴莲&quot;</span>+i);</span><br><span class="line">            psmt.setInt(<span class="number">2</span>,<span class="number">15</span>);</span><br><span class="line">            psmt.setInt(<span class="number">3</span>,<span class="number">100</span>);</span><br><span class="line">            psmt.setString(<span class="number">4</span>,<span class="string">&quot;榴莲是一种神奇的水果&quot;</span>+i);</span><br><span class="line"></span><br><span class="line"><span class="comment">//            批处理操作二：将数据加入一个批次</span></span><br><span class="line">            psmt.addBatch();</span><br><span class="line"><span class="comment">//            每一百个处理一次，分批次处理，每次执行完要记得清空一下队列</span></span><br><span class="line">            <span class="keyword">if</span>(i%<span class="number">100</span>==<span class="number">0</span>)&#123;</span><br><span class="line">                psmt.executeBatch();</span><br><span class="line"><span class="comment">//                记得clear一下</span></span><br><span class="line">                psmt.clearBatch();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"><span class="comment">//        批处理操作三</span></span><br><span class="line">        <span class="type">int</span>[] batch = psmt.executeBatch();</span><br><span class="line">        System.out.println(Arrays.toString(batch));</span><br><span class="line"></span><br><span class="line"><span class="comment">//        7.释放资源</span></span><br><span class="line">        psmt.close();</span><br><span class="line">        connection.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="2-工程">2 工程</h2>
<h3 id="2-1-需求概述和整体框架">2.1 需求概述和整体框架</h3>
<p>以实现一个水果库存系统为例，这个系统需要提供水果的增删改查操作</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">=================欢迎使用水果库存系统=====================</span><br><span class="line">1.查看水果库存列表</span><br><span class="line">2.添加水果库存信息</span><br><span class="line">3.查看特定水果库存信息</span><br><span class="line">4.水果下架</span><br><span class="line">5.退出</span><br><span class="line">======================================================</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>整体框架如下图，在controller里面写调用DAO层的方法，在dao里面写持久层方法，提供接口及其实现类，pojo写实体类，view是客户端视图操作。</p>
<p><img src="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/image-20220621232711636.png" alt="image-20220621232711636"></p>
<h3 id="2-2-最初版本">2.2 最初版本</h3>
<h4 id="2-2-1-pojo">2.2.1 pojo</h4>
<p>pojo包下的Fruit类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zylai.fruit01.pojo;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Zhao YunLai</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2022/06/21/17:33</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Fruit</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> Integer fid;</span><br><span class="line">    <span class="keyword">private</span> String fname;</span><br><span class="line">    <span class="keyword">private</span> Integer price;</span><br><span class="line">    <span class="keyword">private</span> Integer fcount;</span><br><span class="line">    <span class="keyword">private</span> String remark;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Fruit</span><span class="params">()</span>&#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Fruit</span><span class="params">(Integer fid, String fname, String remark)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.fid = fid;</span><br><span class="line">        <span class="built_in">this</span>.fname = fname;</span><br><span class="line">        <span class="built_in">this</span>.remark = remark;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Fruit</span><span class="params">(Integer fid, String fname, Integer price, Integer fcount, String remark)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.fid = fid;</span><br><span class="line">        <span class="built_in">this</span>.fname = fname;</span><br><span class="line">        <span class="built_in">this</span>.price = price;</span><br><span class="line">        <span class="built_in">this</span>.fcount = fcount;</span><br><span class="line">        <span class="built_in">this</span>.remark = remark;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">toString</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> fid+<span class="string">&quot;\t\t&quot;</span>+fname+<span class="string">&quot;\t\t&quot;</span>+price+<span class="string">&quot;\t\t&quot;</span>+fcount+<span class="string">&quot;\t\t&quot;</span>+remark;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> Integer <span class="title function_">getFid</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> fid;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setFid</span><span class="params">(Integer fid)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.fid = fid;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getFname</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> fname;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setFname</span><span class="params">(String fname)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.fname = fname;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> Integer <span class="title function_">getPrice</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> price;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setPrice</span><span class="params">(Integer price)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.price = price;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> Integer <span class="title function_">getFcount</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> fcount;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setFcount</span><span class="params">(Integer fcount)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.fcount = fcount;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getRemark</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> remark;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setRemark</span><span class="params">(String remark)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.remark = remark;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="2-2-2-dao">2.2.2 dao</h4>
<p>FruitDAO接口</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zylai.fruit01.dao;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.zylai.fruit01.pojo.Fruit;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Zhao YunLai</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2022/06/21/18:02</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">FruitDAO</span> &#123;</span><br><span class="line"><span class="comment">//    查询库存列表</span></span><br><span class="line">    List&lt;Fruit&gt; <span class="title function_">getFruitList</span><span class="params">()</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    根据水果名称查询库存</span></span><br><span class="line">    Fruit <span class="title function_">getFruitByName</span><span class="params">(String fname)</span>;</span><br><span class="line"><span class="comment">//    新增水果库存</span></span><br><span class="line">    <span class="type">boolean</span> <span class="title function_">addFruit</span><span class="params">(Fruit fruit)</span>;</span><br><span class="line"><span class="comment">//    修改库存</span></span><br><span class="line">    <span class="type">boolean</span> <span class="title function_">updateFruit</span><span class="params">(Fruit fruit)</span>;</span><br><span class="line"><span class="comment">//    根据水果名称删除记录</span></span><br><span class="line">    <span class="type">boolean</span> <span class="title function_">deleteFruitByName</span><span class="params">(String fname)</span>;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>FruitDAOImpl实现类</p>
<p>注意到这个实现类存在着大量的<strong>代码冗余</strong>，<strong>之后的优化主要对这个类进行优化</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zylai.fruit01.dao.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.zylai.fruit01.dao.FruitDAO;</span><br><span class="line"><span class="keyword">import</span> com.zylai.fruit01.pojo.Fruit;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.sql.*;</span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Zhao YunLai</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2022/06/21/18:05</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">FruitDAOImpl</span> <span class="keyword">implements</span> <span class="title class_">FruitDAO</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">DRIVER</span> <span class="operator">=</span> <span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">URL</span> <span class="operator">=</span> <span class="string">&quot;jdbc:mysql://localhost:3306/fruitdb?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false&quot;</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">USER</span> <span class="operator">=</span> <span class="string">&quot;root&quot;</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">PWD</span> <span class="operator">=</span> <span class="string">&quot;root&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    查询所有的库存信息</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> List&lt;Fruit&gt; <span class="title function_">getFruitList</span><span class="params">()</span> &#123;</span><br><span class="line">        List&lt;Fruit&gt; fruitList = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="type">ResultSet</span> <span class="variable">rs</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line"><span class="comment">//            1.加载驱动</span></span><br><span class="line">            Class.forName(DRIVER);</span><br><span class="line"><span class="comment">//            2.通过驱动获取连接对象</span></span><br><span class="line">             connection= DriverManager.getConnection(URL, USER, PWD);</span><br><span class="line"><span class="comment">//            3.编写SQL语句</span></span><br><span class="line">            <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;select * from t_fruit&quot;</span>;</span><br><span class="line"><span class="comment">//            4.创建预处理命令对象</span></span><br><span class="line">             psmt = connection.prepareStatement(sql);</span><br><span class="line"><span class="comment">//            5.执行查询</span></span><br><span class="line">             rs = psmt.executeQuery();</span><br><span class="line"><span class="comment">//            6.解析查询</span></span><br><span class="line">            <span class="keyword">while</span>(rs.next())&#123;</span><br><span class="line">                <span class="type">int</span> <span class="variable">fid</span> <span class="operator">=</span> rs.getInt(<span class="number">1</span>);</span><br><span class="line">                <span class="type">String</span> <span class="variable">fname</span> <span class="operator">=</span> rs.getString(<span class="number">2</span>);</span><br><span class="line">                <span class="type">int</span> <span class="variable">price</span> <span class="operator">=</span> rs.getInt(<span class="number">3</span>);</span><br><span class="line">                <span class="type">int</span> <span class="variable">fcount</span> <span class="operator">=</span> rs.getInt(<span class="number">4</span>);</span><br><span class="line">                <span class="type">String</span> <span class="variable">remark</span> <span class="operator">=</span> rs.getString(<span class="number">5</span>);</span><br><span class="line"></span><br><span class="line">                <span class="type">Fruit</span> <span class="variable">fruit</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Fruit</span>(fid,fname,price,fcount,remark);</span><br><span class="line">                fruitList.add(fruit);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (ClassNotFoundException | SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;<span class="keyword">finally</span> &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                <span class="keyword">if</span>(rs!=<span class="literal">null</span>)&#123;</span><br><span class="line">                    rs.close();</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(psmt!=<span class="literal">null</span>)&#123;</span><br><span class="line">                    psmt.close();</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(connection!=<span class="literal">null</span>)&#123;</span><br><span class="line">                    connection.close();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">catch</span> (SQLException e) &#123;</span><br><span class="line">                e.printStackTrace();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> fruitList;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    通过水果名称查询记录</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Fruit <span class="title function_">getFruitByName</span><span class="params">(String fname)</span> &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="type">ResultSet</span> <span class="variable">rs</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            Class.forName(DRIVER);</span><br><span class="line">            connection = DriverManager.getConnection(URL,USER,PWD);</span><br><span class="line"></span><br><span class="line">            <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;select * from t_fruit where fname=?&quot;</span>;</span><br><span class="line">            psmt = connection.prepareStatement(sql);</span><br><span class="line">            psmt.setString(<span class="number">1</span>,fname);</span><br><span class="line">            rs= psmt.executeQuery();</span><br><span class="line">            <span class="keyword">if</span>(rs.next())&#123;</span><br><span class="line">                <span class="type">int</span> <span class="variable">fid</span> <span class="operator">=</span> rs.getInt(<span class="string">&quot;fid&quot;</span>);</span><br><span class="line">                <span class="type">int</span> <span class="variable">price</span> <span class="operator">=</span> rs.getInt(<span class="string">&quot;price&quot;</span>);</span><br><span class="line">                <span class="type">int</span> <span class="variable">fcount</span> <span class="operator">=</span> rs.getInt(<span class="string">&quot;fcount&quot;</span>);</span><br><span class="line">                <span class="type">String</span> <span class="variable">remark</span> <span class="operator">=</span> rs.getString(<span class="string">&quot;remark&quot;</span>);</span><br><span class="line"></span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Fruit</span>(fid,fname,price,fcount,remark);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">        &#125; <span class="keyword">catch</span> (ClassNotFoundException | SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;<span class="keyword">finally</span> &#123;</span><br><span class="line">            <span class="keyword">try</span>&#123;</span><br><span class="line">                <span class="keyword">if</span>(rs!=<span class="literal">null</span>)&#123;</span><br><span class="line">                    rs.close();</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(psmt!=<span class="literal">null</span>)&#123;</span><br><span class="line">                    psmt.close();</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(connection!=<span class="literal">null</span>)&#123;</span><br><span class="line">                    connection.close();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">catch</span> (SQLException e) &#123;</span><br><span class="line">                e.printStackTrace();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    添加水果</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">addFruit</span><span class="params">(Fruit fruit)</span> &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            Class.forName(DRIVER);</span><br><span class="line">            connection = DriverManager.getConnection(URL,USER,PWD);</span><br><span class="line">            <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;insert into t_fruit values(0,?,?,?,?)&quot;</span>;</span><br><span class="line">            psmt = connection.prepareStatement(sql);</span><br><span class="line">            psmt.setString(<span class="number">1</span>,fruit.getFname());</span><br><span class="line">            psmt.setInt(<span class="number">2</span>,fruit.getPrice());</span><br><span class="line">            psmt.setInt(<span class="number">3</span>,fruit.getFcount());</span><br><span class="line">            psmt.setString(<span class="number">4</span>,fruit.getRemark());</span><br><span class="line"></span><br><span class="line">            <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> psmt.executeUpdate();</span><br><span class="line">            <span class="keyword">return</span> i&gt;<span class="number">0</span>;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (ClassNotFoundException | SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;<span class="keyword">finally</span> &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                <span class="keyword">if</span>(psmt!=<span class="literal">null</span>)&#123;</span><br><span class="line">                    psmt.close();</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(connection!=<span class="literal">null</span>)&#123;</span><br><span class="line">                    connection.close();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">catch</span> (SQLException e) &#123;</span><br><span class="line">                e.printStackTrace();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    更新水果库存信息</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">updateFruit</span><span class="params">(Fruit fruit)</span> &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            Class.forName(DRIVER);</span><br><span class="line">            connection = DriverManager.getConnection(URL,USER,PWD);</span><br><span class="line">            <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;update t_fruit set fname=?,price=?,fcount=?,remark=? where fid=?&quot;</span>;</span><br><span class="line">            psmt = connection.prepareStatement(sql);</span><br><span class="line">            psmt.setString(<span class="number">1</span>, fruit.getFname());</span><br><span class="line">            psmt.setInt(<span class="number">2</span>,fruit.getPrice());</span><br><span class="line">            psmt.setInt(<span class="number">3</span>,fruit.getFcount());</span><br><span class="line">            psmt.setString(<span class="number">4</span>,fruit.getRemark());</span><br><span class="line">            psmt.setInt(<span class="number">5</span>,fruit.getFid());</span><br><span class="line"></span><br><span class="line">            <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> psmt.executeUpdate();</span><br><span class="line">            <span class="keyword">return</span> i&gt;<span class="number">0</span>;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (ClassNotFoundException | SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;<span class="keyword">finally</span> &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                <span class="keyword">if</span>(psmt!=<span class="literal">null</span>)&#123;</span><br><span class="line">                    psmt.close();</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(connection!=<span class="literal">null</span>)&#123;</span><br><span class="line">                    connection.close();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">catch</span> (SQLException e) &#123;</span><br><span class="line">                e.printStackTrace();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    删除水果</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">deleteFruitByName</span><span class="params">(String fname)</span> &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            Class.forName(DRIVER);</span><br><span class="line">            connection = DriverManager.getConnection(URL,USER,PWD);</span><br><span class="line">            <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;delete from t_fruit where fname=?&quot;</span>;</span><br><span class="line">            psmt = connection.prepareStatement(sql);</span><br><span class="line">            psmt.setString(<span class="number">1</span>,fname);</span><br><span class="line">            <span class="keyword">return</span> psmt.executeUpdate()&gt;<span class="number">0</span>;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (ClassNotFoundException | SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;<span class="keyword">finally</span> &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                <span class="keyword">if</span>(psmt!=<span class="literal">null</span>)&#123;</span><br><span class="line">                    psmt.close();</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(connection!=<span class="literal">null</span>)&#123;</span><br><span class="line">                    connection.close();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">catch</span> (SQLException e) &#123;</span><br><span class="line">                e.printStackTrace();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="2-2-3-controller">2.2.3 controller</h4>
<p>处理请求层，由于业务比较简单，所以一些业务都在controller里面进行</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zylai.fruit01.controller;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.zylai.fruit01.dao.FruitDAO;</span><br><span class="line"><span class="keyword">import</span> com.zylai.fruit01.dao.impl.FruitDAOImpl;</span><br><span class="line"><span class="keyword">import</span> com.zylai.fruit01.pojo.Fruit;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"><span class="keyword">import</span> java.util.Scanner;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Zhao YunLai</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2022/06/21/17:35</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Menu</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="type">Scanner</span> <span class="variable">input</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">    <span class="keyword">private</span> <span class="type">FruitDAO</span> <span class="variable">fruitDAO</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FruitDAOImpl</span>();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">showMainMenu</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;=================欢迎使用水果库存系统=====================&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;1.查看水果库存列表&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;2.添加水果库存信息&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;3.查看特定水果库存信息&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;4.水果下架&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;5.退出&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;======================================================&quot;</span>);</span><br><span class="line">        System.out.print(<span class="string">&quot;请选择：&quot;</span>);</span><br><span class="line">        <span class="type">int</span> <span class="variable">res</span> <span class="operator">=</span> input.nextInt();</span><br><span class="line">        <span class="keyword">while</span>(<span class="literal">true</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(res&lt;<span class="number">1</span>||res&gt;<span class="number">5</span>)&#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;请在1~5当中进行选择！&quot;</span>);</span><br><span class="line">                System.out.print(<span class="string">&quot;请选择：&quot;</span>);</span><br><span class="line">                res = input.nextInt();</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="comment">//    显示所有水果库存</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">showFruitList</span><span class="params">()</span>&#123;</span><br><span class="line">        List&lt;Fruit&gt; fruitList = fruitDAO.getFruitList();</span><br><span class="line">        System.out.println(<span class="string">&quot;------------------------------------------------------&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;编号\t\t名称\t\t单价\t\t库存\t\t备注\t\t&quot;</span>);</span><br><span class="line">        <span class="keyword">if</span>(fruitList==<span class="literal">null</span>||fruitList.size()&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;对不起，库存为空&quot;</span>);</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">for</span> (Fruit fruit : fruitList) &#123;</span><br><span class="line">                System.out.println(fruit);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;------------------------------------------------------&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    添加水果库存信息 -- 业务方法</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">addFruit</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.print(<span class="string">&quot;请输入水果名称：&quot;</span>);</span><br><span class="line">        <span class="type">String</span> <span class="variable">fname</span> <span class="operator">=</span> input.next();</span><br><span class="line"><span class="comment">//       判断是添加库存还是添加一个新水果</span></span><br><span class="line">        <span class="type">Fruit</span> <span class="variable">fruitByName</span> <span class="operator">=</span> fruitDAO.getFruitByName(fname);</span><br><span class="line">        <span class="keyword">if</span>(fruitByName==<span class="literal">null</span>)&#123;<span class="comment">//说明库存中没有这个水果，直接添加</span></span><br><span class="line">            System.out.print(<span class="string">&quot;请输入水果单价：&quot;</span>);</span><br><span class="line">            <span class="type">int</span> <span class="variable">price</span> <span class="operator">=</span> input.nextInt();</span><br><span class="line">            System.out.print(<span class="string">&quot;请输入水果库存量：&quot;</span>);</span><br><span class="line">            <span class="type">int</span> <span class="variable">fcount</span> <span class="operator">=</span> input.nextInt();</span><br><span class="line">            System.out.print(<span class="string">&quot;请输入水果备注：&quot;</span>);</span><br><span class="line">            <span class="type">String</span> <span class="variable">remark</span> <span class="operator">=</span> input.next();</span><br><span class="line">            fruitByName = <span class="keyword">new</span> <span class="title class_">Fruit</span>(<span class="number">0</span>,fname,price,fcount,remark);</span><br><span class="line"><span class="comment">//            调用dao</span></span><br><span class="line">            fruitDAO.addFruit(fruitByName);</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            System.out.print(<span class="string">&quot;请输入追加的库存量：&quot;</span>);</span><br><span class="line">            <span class="type">int</span> <span class="variable">fcount</span> <span class="operator">=</span> input.nextInt();</span><br><span class="line">            fruitByName.setFcount(fruitByName.getFcount()+fcount);</span><br><span class="line">            fruitDAO.updateFruit(fruitByName);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="comment">//    查看特定水果库存信息</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">showFruitInfo</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.print(<span class="string">&quot;请输入水果名称：&quot;</span>);</span><br><span class="line">        <span class="type">String</span> <span class="variable">fname</span> <span class="operator">=</span> input.next();</span><br><span class="line">        <span class="type">Fruit</span> <span class="variable">fruit</span> <span class="operator">=</span> fruitDAO.getFruitByName(fname);</span><br><span class="line">        <span class="keyword">if</span>(fruit == <span class="literal">null</span>)&#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;对不起，没有找到指定的水果库存记录&quot;</span>);</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;------------------------------------------------------&quot;</span>);</span><br><span class="line">            System.out.println(<span class="string">&quot;编号\t\t名称\t\t单价\t\t库存\t\t备注\t\t&quot;</span>);</span><br><span class="line">            System.out.println(fruit);</span><br><span class="line">            System.out.println(<span class="string">&quot;------------------------------------------------------&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">deleteFruit</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.print(<span class="string">&quot;请输入水果名称：&quot;</span>);</span><br><span class="line">        <span class="type">String</span> <span class="variable">fname</span> <span class="operator">=</span> input.next();</span><br><span class="line">        <span class="type">Fruit</span> <span class="variable">fruit</span> <span class="operator">=</span> fruitDAO.getFruitByName(fname);</span><br><span class="line">        <span class="keyword">if</span>(fruit==<span class="literal">null</span>)&#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;对不起，没有找到要下架的水果信息&quot;</span>);</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            System.out.print(<span class="string">&quot;是否下架？（Y/N）&quot;</span>);</span><br><span class="line">            <span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> input.next();</span><br><span class="line">            <span class="keyword">if</span>(<span class="string">&quot;y&quot;</span>.equalsIgnoreCase(str))&#123;</span><br><span class="line">                <span class="type">boolean</span> <span class="variable">b</span> <span class="operator">=</span> fruitDAO.deleteFruitByName(fname);</span><br><span class="line">                <span class="keyword">if</span>(b)&#123;</span><br><span class="line">                    System.out.println(<span class="string">&quot;下架成功！&quot;</span>);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="comment">//    退出</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">exit</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="keyword">do</span>&#123;</span><br><span class="line">            System.out.print(<span class="string">&quot;是否确认退出？(Y/N):&quot;</span>);</span><br><span class="line">            <span class="type">String</span> <span class="variable">res</span> <span class="operator">=</span> input.next();</span><br><span class="line">            <span class="keyword">if</span>(<span class="string">&quot;y&quot;</span>.equalsIgnoreCase(res))&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">            &#125;<span class="keyword">else</span> <span class="keyword">if</span>(<span class="string">&quot;n&quot;</span>.equalsIgnoreCase(res))&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;<span class="keyword">while</span>(<span class="literal">true</span>);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="2-2-4-view">2.2.4 view</h4>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zylai.fruit01.view;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.zylai.fruit01.controller.Menu;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Zhao YunLai</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2022/06/21/17:36</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Client</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Menu</span> <span class="variable">menu</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Menu</span>();</span><br><span class="line">        <span class="type">boolean</span> <span class="variable">flag</span> <span class="operator">=</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">while</span>(!flag)&#123;</span><br><span class="line">            <span class="comment">//        调用主菜单的方法</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">slt</span> <span class="operator">=</span> menu.showMainMenu();</span><br><span class="line">            <span class="keyword">switch</span>(slt)&#123;</span><br><span class="line">                <span class="keyword">case</span> <span class="number">1</span>:</span><br><span class="line">                    menu.showFruitList();</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                <span class="keyword">case</span> <span class="number">2</span>:</span><br><span class="line">                    menu.addFruit();</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                <span class="keyword">case</span> <span class="number">3</span>:</span><br><span class="line">                    menu.showFruitInfo();</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                <span class="keyword">case</span> <span class="number">4</span>:</span><br><span class="line">                    menu.deleteFruit();</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                <span class="keyword">case</span> <span class="number">5</span>:</span><br><span class="line">                    flag = menu.exit();</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;谢谢使用&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="2-2-5-最初版总结">2.2.5 最初版总结</h4>
<p>代码的冗余量很大，主要是dao层的实现类，每个方法都要重复建立驱动、获取连接、关闭资源等操作。</p>
<h3 id="2-3-改进：对于FruitDAOImpl中获取连接操作以及释放资源操作做了提取">2.3 改进：对于FruitDAOImpl中获取连接操作以及释放资源操作做了提取</h3>
<p>这次的改进就是对于FruitDAOImpl中获取连接操作以及释放资源操作做了提取</p>
<p>如下：将加载驱动获取连接封装在getConnection方法中，将关闭资源封装在close方法中</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line">    <span class="keyword">private</span> Connection <span class="title function_">getConnection</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">//       1.加载驱动</span></span><br><span class="line">            Class.forName(DRIVER);</span><br><span class="line">            <span class="comment">//            2.通过驱动获取连接对象</span></span><br><span class="line">            <span class="keyword">return</span> DriverManager.getConnection(URL, USER, PWD);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (ClassNotFoundException | SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">close</span><span class="params">(Connection connection,PreparedStatement psmt, ResultSet rs)</span>&#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">if</span>(rs!=<span class="literal">null</span>)&#123;</span><br><span class="line">                rs.close();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(psmt!=<span class="literal">null</span>)&#123;</span><br><span class="line">                psmt.close();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(connection!=<span class="literal">null</span>)&#123;</span><br><span class="line">                connection.close();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//实际中使用</span></span><br><span class="line"><span class="comment">//    通过水果名称查询记录</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Fruit <span class="title function_">getFruitByName</span><span class="params">(String fname)</span> &#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="type">ResultSet</span> <span class="variable">rs</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line"></span><br><span class="line">            connection = getConnection();</span><br><span class="line"></span><br><span class="line">            <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;select * from t_fruit where fname=?&quot;</span>;</span><br><span class="line">            psmt = connection.prepareStatement(sql);</span><br><span class="line">            psmt.setString(<span class="number">1</span>,fname);</span><br><span class="line">            rs= psmt.executeQuery();</span><br><span class="line">            <span class="keyword">if</span>(rs.next())&#123;</span><br><span class="line">                <span class="type">int</span> <span class="variable">fid</span> <span class="operator">=</span> rs.getInt(<span class="string">&quot;fid&quot;</span>);</span><br><span class="line">                <span class="type">int</span> <span class="variable">price</span> <span class="operator">=</span> rs.getInt(<span class="string">&quot;price&quot;</span>);</span><br><span class="line">                <span class="type">int</span> <span class="variable">fcount</span> <span class="operator">=</span> rs.getInt(<span class="string">&quot;fcount&quot;</span>);</span><br><span class="line">                <span class="type">String</span> <span class="variable">remark</span> <span class="operator">=</span> rs.getString(<span class="string">&quot;remark&quot;</span>);</span><br><span class="line"></span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Fruit</span>(fid,fname,price,fcount,remark);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">        &#125; <span class="keyword">catch</span> ( SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;<span class="keyword">finally</span> &#123;</span><br><span class="line">            close(connection,psmt,rs);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<h3 id="2-4-改进：设置抽象类，并抽取增删改操作">2.4 改进：设置抽象类，并抽取增删改操作</h3>
<p>可以看到下面这个三个操作的步骤完全一样，<strong>不一样的地方只是SQL语句和psmt设置的参数</strong><br>
因此可以将这些相同的操作抽取出来</p>
<ul>
<li>
<p>addFruit:<br>
1.获取连接<br>
2.编写SQL<br>
3.psmt<br>
4.执行更新<br>
5.关闭资源</p>
</li>
<li>
<p>updateFruit：<br>
1.获取连接<br>
2.编写SQL<br>
3.psmt<br>
4.执行更新<br>
5.关闭资源</p>
</li>
<li>
<p>deleteFruit<br>
1.获取连接<br>
2.编写SQL<br>
3.psmt<br>
4.执行更新<br>
5.关闭连接</p>
</li>
</ul>
<p>此外，这里只是涉及到一个表的操作，当有多个表时，就涉及到多个dao类，而这多个dao类都需要这共同的驱动地址，数据库url，用户名，密码，获取驱动方法，关闭资源的方法，抽取增删改操作方法。</p>
<p>因此，加入一个抽象类baseDAO，里面提供公共的常量和方法，并且把抽取的增删改方法加入</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zylai.fruit.dao.base;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.sql.*;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Zhao YunLai</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2022/06/21/21:45</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title class_">BaseDAO</span> &#123;</span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">DRIVER</span> <span class="operator">=</span> <span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>;</span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">URL</span> <span class="operator">=</span> <span class="string">&quot;jdbc:mysql://localhost:3306/fruitdb?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false&quot;</span>;</span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">USER</span> <span class="operator">=</span> <span class="string">&quot;root&quot;</span>;</span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">PWD</span> <span class="operator">=</span> <span class="string">&quot;root&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">protected</span> Connection <span class="title function_">getConnection</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">//       1.加载驱动</span></span><br><span class="line">            Class.forName(DRIVER);</span><br><span class="line">            <span class="comment">//            2.通过驱动获取连接对象</span></span><br><span class="line">            <span class="keyword">return</span> DriverManager.getConnection(URL, USER, PWD);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (ClassNotFoundException | SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    关闭资源</span></span><br><span class="line">    <span class="keyword">protected</span>  <span class="keyword">void</span> <span class="title function_">close</span><span class="params">(Connection connection, PreparedStatement psmt, ResultSet rs)</span>&#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">if</span>(rs!=<span class="literal">null</span>)&#123;</span><br><span class="line">                rs.close();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(psmt!=<span class="literal">null</span>)&#123;</span><br><span class="line">                psmt.close();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(connection!=<span class="literal">null</span>)&#123;</span><br><span class="line">                connection.close();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    执行更新，返回影响行数   </span></span><br><span class="line">    <span class="keyword">protected</span> <span class="type">int</span> <span class="title function_">executeUpdate</span><span class="params">(String sql,Object... params)</span>&#123;</span><br><span class="line">        <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            connection = getConnection();</span><br><span class="line">            psmt = connection.prepareStatement(sql);</span><br><span class="line">            <span class="keyword">if</span>(params!=<span class="literal">null</span> &amp;&amp; params.length&gt;<span class="number">0</span>)&#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; params.length; i++) &#123;</span><br><span class="line">                    psmt.setObject(i+<span class="number">1</span>,params[i]);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> psmt.executeUpdate();</span><br><span class="line">        &#125; <span class="keyword">catch</span> ( SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;<span class="keyword">finally</span> &#123;</span><br><span class="line">            close(connection,psmt,<span class="literal">null</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>然后让daoImpl继承该抽象类</p>
<p>由于没有涉及到查询的改进，这里省去查询的方法。可以看到对于增删改方法，只需要调用父类的更新执行方法，传入sql语句和参数即可完成业务。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zylai.fruit.dao.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.zylai.fruit.dao.FruitDAO;</span><br><span class="line"><span class="keyword">import</span> com.zylai.fruit.dao.base.BaseDAO;</span><br><span class="line"><span class="keyword">import</span> com.zylai.fruit.pojo.Fruit;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.sql.*;</span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Zhao YunLai</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2022/06/21/18:05</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">FruitDAOImpl</span> <span class="keyword">extends</span> <span class="title class_">BaseDAO</span> <span class="keyword">implements</span> <span class="title class_">FruitDAO</span> &#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    添加水果</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">addFruit</span><span class="params">(Fruit fruit)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;insert into t_fruit values(0,?,?,?,?)&quot;</span>;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">super</span>.executeUpdate(sql,fruit.getFname(),fruit.getPrice(),fruit.getFcount(),fruit.getRemark())&gt;<span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    更新水果库存信息</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">updateFruit</span><span class="params">(Fruit fruit)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;update t_fruit set fname=?,price=?,fcount=?,remark=? where fid=?&quot;</span>;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">super</span>.executeUpdate(sql,fruit.getFname(),fruit.getPrice(),fruit.getFcount(),fruit.getRemark(),fruit.getFid())&gt;<span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    删除水果</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">deleteFruitByName</span><span class="params">(String fname)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;delete from t_fruit where fname=?&quot;</span>;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">super</span>.executeUpdate(sql,fname)&gt;<span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="2-5-改进：抽取查询操作">2.5 改进：抽取查询操作</h3>
<h4 id="2-5-1-使用泛型">2.5.1 使用泛型</h4>
<p>通过执行查询操作返回查询的结果集，然后通过get方法得到指定列的值赋值给实体类比如Fruit，而对于baseDAO会有多个DAOImpl继承它，因此不能把实体类写死，所以采用泛型。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title class_">BaseDAO</span>&lt;T&gt; &#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">FruitDAOImpl</span> <span class="keyword">extends</span> <span class="title class_">BaseDAO</span>&lt;Fruit&gt; <span class="keyword">implements</span> <span class="title class_">FruitDAO</span> &#123;&#125;</span><br></pre></td></tr></table></figure>
<h4 id="2-5-2-通过反射得到真正的类">2.5.2 通过反射得到真正的类</h4>
<p>因为泛型只是一个符号，我们不能直接通过泛型创建实例，所以用到反射技术来确定真正的实体类。</p>
<p>首先在类中定义Class 属性</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//    T的Class对象</span></span><br><span class="line">    <span class="keyword">private</span> Class entityClass;</span><br></pre></td></tr></table></figure>
<p>在BaseDAO的无参构造器中，确定真正的实体类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">    <span class="keyword">public</span> <span class="title function_">BaseDAO</span><span class="params">()</span>&#123;</span><br><span class="line"><span class="comment">//        getClass获取Class对象，当前我们执行的是new FruitDAOImpl（），创建的是FruitDAOImpl实例</span></span><br><span class="line"><span class="comment">//        那么构造方法首先会调用父类（BaseDAO）的无参构造方法</span></span><br><span class="line"><span class="comment">//        因此此处的getClass方法执行，获取的是FruitDAOImpl的Class</span></span><br><span class="line"><span class="comment">//        所以使用getGenericSuperclass</span></span><br><span class="line"><span class="comment">//        getGenericSuperclass是获取父类的泛型，即获取BaseDAO的泛型</span></span><br><span class="line">        <span class="type">Type</span> <span class="variable">genericSuperclass</span> <span class="operator">=</span> getClass().getGenericSuperclass();</span><br><span class="line"><span class="comment">//         ParameterizedType:参数化类型</span></span><br><span class="line"><span class="comment">//        获取&lt;T&gt;（注意，泛型可以传递多个如&lt;T,A,B&gt;，所以返回值是一个数组）中的T的真是类型</span></span><br><span class="line">        Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass).getActualTypeArguments();</span><br><span class="line">        <span class="type">Type</span> <span class="variable">actualType</span> <span class="operator">=</span> actualTypeArguments[<span class="number">0</span>];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            entityClass = Class.forName(actualType.getTypeName());</span><br><span class="line">        &#125; <span class="keyword">catch</span> (ClassNotFoundException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<h4 id="2-5-3-查询方法">2.5.3 查询方法</h4>
<p>在处理结果集时我们不知道T到底有几个参数，是什么类型。因此，我们需要获取结果集的元数据，所谓元数据就是描述结果集数据的数据，简单来讲，就是这个结果集有哪些列，什么类型等等。</p>
<p>之后通过Class对象创建一个T的实例进行操作即可</p>
<p>先定义一个工具函数：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//    通过反射，给obj对象的property属性赋propertyValue值</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">setValue</span><span class="params">(Object obj,String property,Object propertyValue)</span>&#123;</span><br><span class="line">        <span class="type">Class</span> <span class="variable">clazz</span> <span class="operator">=</span> obj.getClass();</span><br><span class="line"><span class="comment">//        获取property这个字符串对应的属性名，比如“fid”去找obj中的fid属性</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Field</span> <span class="variable">field</span>  <span class="operator">=</span> clazz.getDeclaredField(property);</span><br><span class="line">            <span class="keyword">if</span>(field!=<span class="literal">null</span>)&#123;</span><br><span class="line">                <span class="comment">//            强制访问</span></span><br><span class="line">                field.setAccessible(<span class="literal">true</span>);</span><br><span class="line">                <span class="comment">//为obj对象设置filed属性的值</span></span><br><span class="line">                field.set(obj,propertyValue);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (NoSuchFieldException | IllegalAccessException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<p>执行查询的函数：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//    执行查询</span></span><br><span class="line">    <span class="keyword">protected</span> List&lt;T&gt; <span class="title function_">executeQuery</span><span class="params">(String sql,Object... params)</span>&#123;</span><br><span class="line">        List&lt;T&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line"><span class="comment">//            获取连接</span></span><br><span class="line">            connection = getConnection();</span><br><span class="line"><span class="comment">//            设置预处理对象</span></span><br><span class="line">            psmt = connection.prepareStatement(sql);</span><br><span class="line"><span class="comment">//            设置参数</span></span><br><span class="line">            setParams(psmt,params);</span><br><span class="line"><span class="comment">//            执行查询</span></span><br><span class="line">            rs= psmt.executeQuery();</span><br><span class="line"><span class="comment">//            处理结果集</span></span><br><span class="line"><span class="comment">//            难点在于如何处理T，我们不知道T是什么类型并且不知道T有多少个参数</span></span><br><span class="line"><span class="comment">//            通过rs可以获取结果集的元数据</span></span><br><span class="line"><span class="comment">//            元数据：描述结果集数据的数据，简单讲，就是这个结果接有哪些列，什么类型等等</span></span><br><span class="line">            <span class="type">ResultSetMetaData</span> <span class="variable">metaData</span> <span class="operator">=</span> rs.getMetaData();</span><br><span class="line">            <span class="type">int</span> <span class="variable">columnCount</span> <span class="operator">=</span> metaData.getColumnCount();</span><br><span class="line">            <span class="keyword">while</span>(rs.next())&#123;</span><br><span class="line">                <span class="type">T</span> <span class="variable">entity</span> <span class="operator">=</span> (T)entityClass.newInstance();</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; columnCount; i++) &#123;</span><br><span class="line"><span class="comment">//               获取列名</span></span><br><span class="line">                    <span class="type">String</span> <span class="variable">columnName</span> <span class="operator">=</span> metaData.getColumnName(i + <span class="number">1</span>);</span><br><span class="line"><span class="comment">//                获取列对应的值</span></span><br><span class="line">                    <span class="type">Object</span> <span class="variable">columnValue</span> <span class="operator">=</span> rs.getObject(i + <span class="number">1</span>);</span><br><span class="line"><span class="comment">//                    这里获取了列名，就需要根据列名把值填充给entity对象</span></span><br><span class="line">                    setValue(entity,columnName,columnValue);</span><br><span class="line">                &#125;</span><br><span class="line">                list.add(entity);</span><br><span class="line"></span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IllegalAccessException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (InstantiationException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            close(connection,psmt,rs);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="2-5-4-改进后的整个BaseDAO类为：">2.5.4 改进后的整个BaseDAO类为：</h4>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zylai.fruit.dao.base;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.lang.reflect.Field;</span><br><span class="line"><span class="keyword">import</span> java.lang.reflect.ParameterizedType;</span><br><span class="line"><span class="keyword">import</span> java.lang.reflect.Type;</span><br><span class="line"><span class="keyword">import</span> java.sql.*;</span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Zhao YunLai</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2022/06/21/21:45</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title class_">BaseDAO</span>&lt;T&gt; &#123;</span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">DRIVER</span> <span class="operator">=</span> <span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>;</span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">URL</span> <span class="operator">=</span> <span class="string">&quot;jdbc:mysql://localhost:3306/fruitdb?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false&quot;</span>;</span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">USER</span> <span class="operator">=</span> <span class="string">&quot;root&quot;</span>;</span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">PWD</span> <span class="operator">=</span> <span class="string">&quot;root&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    老师是吧这几个放到这里的，我觉得可能会出现并发问题，不过目前不考虑这个</span></span><br><span class="line">    <span class="keyword">protected</span> <span class="type">Connection</span> <span class="variable">connection</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">    <span class="keyword">protected</span> <span class="type">PreparedStatement</span> <span class="variable">psmt</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">    <span class="keyword">protected</span> <span class="type">ResultSet</span> <span class="variable">rs</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    T的Class对象</span></span><br><span class="line">    <span class="keyword">private</span> Class entityClass;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">BaseDAO</span><span class="params">()</span>&#123;</span><br><span class="line"><span class="comment">//        getClass获取Class对象，当前我们执行的是new FruitDAOImpl（），创建的是FruitDAOImpl实例</span></span><br><span class="line"><span class="comment">//        那么构造方法首先会调用父类（BaseDAO）的无参构造方法</span></span><br><span class="line"><span class="comment">//        因此此处的getClass方法执行，获取的是FruitDAOImpl的Class</span></span><br><span class="line"><span class="comment">//        所以使用getGenericSuperclass</span></span><br><span class="line"><span class="comment">//        getGenericSuperclass是获取父类的泛型，即获取BaseDAO的泛型</span></span><br><span class="line">        <span class="type">Type</span> <span class="variable">genericSuperclass</span> <span class="operator">=</span> getClass().getGenericSuperclass();</span><br><span class="line"><span class="comment">//         ParameterizedType:参数化类型</span></span><br><span class="line"><span class="comment">//        获取&lt;T&gt;（注意，泛型可以传递多个如&lt;T,A,B&gt;，所以返回值是一个数组）中的T的真是类型</span></span><br><span class="line">        Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass).getActualTypeArguments();</span><br><span class="line">        <span class="type">Type</span> <span class="variable">actualType</span> <span class="operator">=</span> actualTypeArguments[<span class="number">0</span>];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            entityClass = Class.forName(actualType.getTypeName());</span><br><span class="line">        &#125; <span class="keyword">catch</span> (ClassNotFoundException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">protected</span> Connection <span class="title function_">getConnection</span><span class="params">()</span>&#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">//       1.加载驱动</span></span><br><span class="line">            Class.forName(DRIVER);</span><br><span class="line">            <span class="comment">//            2.通过驱动获取连接对象</span></span><br><span class="line">            <span class="keyword">return</span> DriverManager.getConnection(URL, USER, PWD);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (ClassNotFoundException | SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    关闭资源</span></span><br><span class="line">    <span class="keyword">protected</span>  <span class="keyword">void</span> <span class="title function_">close</span><span class="params">(Connection connection, PreparedStatement psmt, ResultSet rs)</span>&#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">if</span>(rs!=<span class="literal">null</span>)&#123;</span><br><span class="line">                rs.close();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(psmt!=<span class="literal">null</span>)&#123;</span><br><span class="line">                psmt.close();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(connection!=<span class="literal">null</span>)&#123;</span><br><span class="line">                connection.close();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="comment">//    给预处理对象设置参数</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">setParams</span><span class="params">(PreparedStatement psmt,Object... params)</span> <span class="keyword">throws</span> SQLException &#123;</span><br><span class="line">        <span class="keyword">if</span>(params!=<span class="literal">null</span> &amp;&amp; params.length&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; params.length; i++) &#123;</span><br><span class="line">                psmt.setObject(i+<span class="number">1</span>,params[i]);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//    通过反射，给obj对象的property属性赋propertyValue值</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">setValue</span><span class="params">(Object obj,String property,Object propertyValue)</span>&#123;</span><br><span class="line">        <span class="type">Class</span> <span class="variable">clazz</span> <span class="operator">=</span> obj.getClass();</span><br><span class="line"><span class="comment">//        获取property这个字符串对应的属性名，比如“fid”去找obj中的fid属性</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Field</span> <span class="variable">field</span>  <span class="operator">=</span> clazz.getDeclaredField(property);</span><br><span class="line">            <span class="keyword">if</span>(field!=<span class="literal">null</span>)&#123;</span><br><span class="line">                <span class="comment">//            强制访问</span></span><br><span class="line">                field.setAccessible(<span class="literal">true</span>);</span><br><span class="line">                <span class="comment">//为obj对象设置filed属性的值</span></span><br><span class="line">                field.set(obj,propertyValue);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (NoSuchFieldException | IllegalAccessException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    执行查询</span></span><br><span class="line">    <span class="keyword">protected</span> List&lt;T&gt; <span class="title function_">executeQuery</span><span class="params">(String sql,Object... params)</span>&#123;</span><br><span class="line">        List&lt;T&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line"><span class="comment">//            获取连接</span></span><br><span class="line">            connection = getConnection();</span><br><span class="line"><span class="comment">//            设置预处理对象</span></span><br><span class="line">            psmt = connection.prepareStatement(sql);</span><br><span class="line"><span class="comment">//            设置参数</span></span><br><span class="line">            setParams(psmt,params);</span><br><span class="line"><span class="comment">//            执行查询</span></span><br><span class="line">            rs= psmt.executeQuery();</span><br><span class="line"><span class="comment">//            处理结果集</span></span><br><span class="line"><span class="comment">//            难点在于如何处理T，我们不知道T是什么类型并且不知道T有多少个参数</span></span><br><span class="line"><span class="comment">//            通过rs可以获取结果集的元数据</span></span><br><span class="line"><span class="comment">//            元数据：描述结果集数据的数据，简单讲，就是这个结果接有哪些列，什么类型等等</span></span><br><span class="line">            <span class="type">ResultSetMetaData</span> <span class="variable">metaData</span> <span class="operator">=</span> rs.getMetaData();</span><br><span class="line">            <span class="type">int</span> <span class="variable">columnCount</span> <span class="operator">=</span> metaData.getColumnCount();</span><br><span class="line">            <span class="keyword">while</span>(rs.next())&#123;</span><br><span class="line">                <span class="type">T</span> <span class="variable">entity</span> <span class="operator">=</span> (T)entityClass.newInstance();</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; columnCount; i++) &#123;</span><br><span class="line"><span class="comment">//               获取列名</span></span><br><span class="line">                    <span class="type">String</span> <span class="variable">columnName</span> <span class="operator">=</span> metaData.getColumnName(i + <span class="number">1</span>);</span><br><span class="line"><span class="comment">//                获取列对应的值</span></span><br><span class="line">                    <span class="type">Object</span> <span class="variable">columnValue</span> <span class="operator">=</span> rs.getObject(i + <span class="number">1</span>);</span><br><span class="line"><span class="comment">//                    这里获取了列名，就需要根据列名把值填充给entity对象</span></span><br><span class="line">                    setValue(entity,columnName,columnValue);</span><br><span class="line">                &#125;</span><br><span class="line">                list.add(entity);</span><br><span class="line"></span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IllegalAccessException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (InstantiationException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            close(connection,psmt,rs);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    通过查询返回一条记录</span></span><br><span class="line">    <span class="keyword">protected</span> T <span class="title function_">load</span><span class="params">(String sql,Object... params)</span>&#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line"><span class="comment">//            获取连接</span></span><br><span class="line">            connection = getConnection();</span><br><span class="line"><span class="comment">//            设置预处理对象</span></span><br><span class="line">            psmt = connection.prepareStatement(sql);</span><br><span class="line"><span class="comment">//            设置参数</span></span><br><span class="line">            setParams(psmt,params);</span><br><span class="line"><span class="comment">//            执行查询</span></span><br><span class="line">            rs= psmt.executeQuery();</span><br><span class="line"><span class="comment">//            处理结果集</span></span><br><span class="line"><span class="comment">//            难点在于如何处理T，我们不知道T是什么类型并且不知道T有多少个参数</span></span><br><span class="line"><span class="comment">//            通过rs可以获取结果集的元数据</span></span><br><span class="line"><span class="comment">//            元数据：描述结果集数据的数据，简单讲，就是这个结果接有哪些列，什么类型等等</span></span><br><span class="line">            <span class="type">ResultSetMetaData</span> <span class="variable">metaData</span> <span class="operator">=</span> rs.getMetaData();</span><br><span class="line">            <span class="type">int</span> <span class="variable">columnCount</span> <span class="operator">=</span> metaData.getColumnCount();</span><br><span class="line">            <span class="keyword">if</span> (rs.next())&#123;</span><br><span class="line">                <span class="type">T</span> <span class="variable">entity</span> <span class="operator">=</span> (T)entityClass.newInstance();</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; columnCount; i++) &#123;</span><br><span class="line"><span class="comment">//               获取列名</span></span><br><span class="line">                    <span class="type">String</span> <span class="variable">columnName</span> <span class="operator">=</span> metaData.getColumnName(i + <span class="number">1</span>);</span><br><span class="line"><span class="comment">//                获取列对应的值</span></span><br><span class="line">                    <span class="type">Object</span> <span class="variable">columnValue</span> <span class="operator">=</span> rs.getObject(i + <span class="number">1</span>);</span><br><span class="line"><span class="comment">//                    这里获取了列名，就需要根据列名把值填充给entity对象</span></span><br><span class="line">                    setValue(entity,columnName,columnValue);</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">return</span> entity;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IllegalAccessException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (InstantiationException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            close(connection,psmt,rs);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    执行复杂的查询，返回统计结果，这个方法暂时没有用到</span></span><br><span class="line">    <span class="keyword">protected</span> Object[] executeComplexQuery(String sql,Object... params)&#123;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line"><span class="comment">//            获取连接</span></span><br><span class="line">            connection = getConnection();</span><br><span class="line"><span class="comment">//            设置预处理对象</span></span><br><span class="line">            psmt = connection.prepareStatement(sql);</span><br><span class="line"><span class="comment">//            设置参数</span></span><br><span class="line">            setParams(psmt,params);</span><br><span class="line"><span class="comment">//            执行查询</span></span><br><span class="line">            rs= psmt.executeQuery();</span><br><span class="line"><span class="comment">//            处理结果集</span></span><br><span class="line"><span class="comment">//            难点在于如何处理T，我们不知道T是什么类型并且不知道T有多少个参数</span></span><br><span class="line"><span class="comment">//            通过rs可以获取结果集的元数据</span></span><br><span class="line"><span class="comment">//            元数据：描述结果集数据的数据，简单讲，就是这个结果接有哪些列，什么类型等等</span></span><br><span class="line">            <span class="type">ResultSetMetaData</span> <span class="variable">metaData</span> <span class="operator">=</span> rs.getMetaData();</span><br><span class="line">            <span class="type">int</span> <span class="variable">columnCount</span> <span class="operator">=</span> metaData.getColumnCount();</span><br><span class="line">            <span class="keyword">if</span> (rs.next())&#123;</span><br><span class="line">                Object[] columnValueArr = <span class="keyword">new</span> <span class="title class_">Object</span>[columnCount];</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; columnCount; i++) &#123;</span><br><span class="line"><span class="comment">//                获取列对应的值</span></span><br><span class="line">                    <span class="type">Object</span> <span class="variable">columnValue</span> <span class="operator">=</span> rs.getObject(i + <span class="number">1</span>);</span><br><span class="line">                    columnValueArr[i]=columnValue;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">return</span> columnValueArr;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (SQLException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            close(connection,psmt,rs);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="3-数据库连接池">3 数据库连接池</h2>
<h3 id="3-1-概述和优势">3.1 概述和优势</h3>
<p>之前的的连接都是用的时候才创建连接，当使用完成之后就销毁，这样效率很低，浪费资源。</p>
<p>使用数据库连接池就可以先创建多个连接对象放到连接池中，等到使用的时候直接从连接池中取出来，用完之后归还。</p>
<h4 id="3-1-1-好处：">3.1.1 好处：</h4>
<ol>
<li>响应时间更快</li>
<li>连接对象的利用率更高</li>
</ol>
<h4 id="3-1-2详细配置参数：">3.1.2详细配置参数：</h4>
<p>不需要背，只是参考，记住主要用的几个就可以了</p>
<table>
<thead>
<tr>
<th><strong>配置</strong></th>
<th><strong>缺省</strong></th>
<th><strong>说明</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>name</td>
<td></td>
<td>配置这个属性的意义在于，如果存在多个数据源，监控的时候可以通过名字来区分开来。   如果没有配置，将会生成一个名字，格式是：”DataSource-” +   System.identityHashCode(this)</td>
</tr>
<tr>
<td>url</td>
<td></td>
<td>连接数据库的url，不同数据库不一样。例如：mysql :   jdbc:mysql://10.20.153.104:3306/druid2      oracle :   jdbc:oracle:thin:@10.20.149.85:1521:ocnauto</td>
</tr>
<tr>
<td>username</td>
<td></td>
<td>连接数据库的用户名</td>
</tr>
<tr>
<td>password</td>
<td></td>
<td>连接数据库的密码。如果你不希望密码直接写在配置文件中，可以使用ConfigFilter。详细看这里：<a target="_blank" rel="noopener" href="https://github.com/alibaba/druid/wiki/%E4%BD%BF%E7%94%A8ConfigFilter">https://github.com/alibaba/druid/wiki/使用ConfigFilter</a></td>
</tr>
<tr>
<td>driverClassName</td>
<td></td>
<td>根据url自动识别   这一项可配可不配，如果不配置druid会根据url自动识别dbType，然后选择相应的driverClassName(建议配置下)</td>
</tr>
<tr>
<td>initialSize</td>
<td>0</td>
<td>初始化时建立物理连接的个数。初始化发生在显示调用init方法，或者第一次getConnection时</td>
</tr>
<tr>
<td>maxActive</td>
<td>8</td>
<td>最大连接池数量</td>
</tr>
<tr>
<td>maxIdle</td>
<td>8</td>
<td>已经不再使用，配置了也没效果</td>
</tr>
<tr>
<td>minIdle</td>
<td></td>
<td>最小连接池数量</td>
</tr>
<tr>
<td>maxWait</td>
<td></td>
<td>获取连接时最大等待时间，单位毫秒。配置了maxWait之后，缺省启用公平锁，并发效率会有所下降，如果需要可以通过配置useUnfairLock属性为true使用非公平锁。</td>
</tr>
<tr>
<td>poolPreparedStatements</td>
<td>false</td>
<td>是否缓存preparedStatement，也就是PSCache。PSCache对支持游标的数据库性能提升巨大，比如说oracle。在mysql下建议关闭。</td>
</tr>
<tr>
<td>maxOpenPreparedStatements</td>
<td>-1</td>
<td>要启用PSCache，必须配置大于0，当大于0时，poolPreparedStatements自动触发修改为true。在Druid中，不会存在Oracle下PSCache占用内存过多的问题，可以把这个数值配置大一些，比如说100</td>
</tr>
<tr>
<td>validationQuery</td>
<td></td>
<td>用来检测连接是否有效的sql，要求是一个查询语句。如果validationQuery为null，testOnBorrow、testOnReturn、testWhileIdle都不会其作用。</td>
</tr>
<tr>
<td>testOnBorrow</td>
<td>true</td>
<td>申请连接时执行validationQuery检测连接是否有效，做了这个配置会降低性能。</td>
</tr>
<tr>
<td>testOnReturn</td>
<td>false</td>
<td>归还连接时执行validationQuery检测连接是否有效，做了这个配置会降低性能</td>
</tr>
<tr>
<td>testWhileIdle</td>
<td>false</td>
<td>建议配置为true，不影响性能，并且保证安全性。申请连接的时候检测，如果空闲时间大于timeBetweenEvictionRunsMillis，执行validationQuery检测连接是否有效。</td>
</tr>
<tr>
<td>timeBetweenEvictionRunsMillis</td>
<td></td>
<td>有两个含义： 1)Destroy线程会检测连接的间隔时间2)testWhileIdle的判断依据，详细看testWhileIdle属性的说明</td>
</tr>
<tr>
<td>numTestsPerEvictionRun</td>
<td></td>
<td>不再使用，一个DruidDataSource只支持一个EvictionRun</td>
</tr>
<tr>
<td>minEvictableIdleTimeMillis</td>
<td></td>
<td></td>
</tr>
<tr>
<td>connectionInitSqls</td>
<td></td>
<td>物理连接初始化的时候执行的sql</td>
</tr>
<tr>
<td>exceptionSorter</td>
<td></td>
<td>根据dbType自动识别   当数据库抛出一些不可恢复的异常时，抛弃连接</td>
</tr>
<tr>
<td>filters</td>
<td></td>
<td>属性类型是字符串，通过别名的方式配置扩展插件，常用的插件有：   监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wall</td>
</tr>
<tr>
<td>proxyFilters</td>
<td></td>
<td>类型是List，如果同时配置了filters和proxyFilters，是组合关系，并非替换关系</td>
</tr>
</tbody>
</table>
<h3 id="3-2-使用">3.2 使用</h3>
<h4 id="3-2-1-基础使用">3.2.1 基础使用</h4>
<p>将对应的jar引入到项目中之后，创建<code>DruidDataSource</code>对象，进行连接即可。</p>
<p>注意:</p>
<ol>
<li>被close的连接对象并没有真正关闭，而是将状态重新设置为空闲状态放回池子</li>
<li>没有被close的连接对象会被一直占用，那么下次继续获取连接对象，是不会获取到这个对象的</li>
<li>对于conn1对象指向别的东西，原始情况下jvm会回收conn1之前指向的对象，但是连接池中的连接默认有一个变量指着，所以不会被回收</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zylai.jdbc;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.alibaba.druid.pool.DruidDataSource;</span><br><span class="line"><span class="keyword">import</span> com.alibaba.druid.pool.DruidPooledConnection;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.sql.Connection;</span><br><span class="line"><span class="keyword">import</span> java.sql.SQLException;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Zhao YunLai</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2022/06/22/14:13</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo02Druid</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> SQLException &#123;</span><br><span class="line"></span><br><span class="line">        <span class="type">DruidDataSource</span> <span class="variable">dataSource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DruidDataSource</span>();</span><br><span class="line"></span><br><span class="line">        dataSource.setDriverClassName(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>);</span><br><span class="line">        dataSource.setUrl(<span class="string">&quot;jdbc:mysql://localhost:3306/fruitdb?&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8&quot;</span>);</span><br><span class="line">        dataSource.setUsername(<span class="string">&quot;root&quot;</span>);</span><br><span class="line">        dataSource.setPassword(<span class="string">&quot;root&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//        证明两点：</span></span><br><span class="line"><span class="comment">//        1.被close的连接对象并没有真正关闭，而是将状态重新设置为空闲状态放回池子</span></span><br><span class="line"><span class="comment">//        2.没有被close的连接对象会被一直占用，那么下次继续获取连接对象，是不会获取到这个对象的</span></span><br><span class="line"><span class="comment">//        对于conn1对象指向别的东西，原始情况下jvm会回收conn1之前指向的对象，但是连接池中的连接默认有一个变量指着，所以不会被回收</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">5</span>; i++) &#123;</span><br><span class="line">            <span class="type">Connection</span> <span class="variable">conn1</span> <span class="operator">=</span> dataSource.getConnection();</span><br><span class="line">            <span class="type">Connection</span> <span class="variable">conn2</span> <span class="operator">=</span> dataSource.getConnection();</span><br><span class="line"></span><br><span class="line">            System.out.println(conn1);</span><br><span class="line">            System.out.println(conn2);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span>(i%<span class="number">3</span>==<span class="number">0</span>)&#123;</span><br><span class="line">                conn1.close();</span><br><span class="line">                conn2.close();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="3-2-2-验证连接池的部分参数">3.2.2 验证连接池的部分参数</h4>
<p>这里以最大连接数和最长等待时间为例，当获取完所有的连接之后，再去获取连接超过指定的等待时间会抛出异常</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zylai.jdbc;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.alibaba.druid.pool.DruidDataSource;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.sql.Connection;</span><br><span class="line"><span class="keyword">import</span> java.sql.SQLException;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Zhao YunLai</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2022/06/22/14:13</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 验证连接池的部分参数</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo03Druid</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> SQLException &#123;</span><br><span class="line"></span><br><span class="line">        <span class="type">DruidDataSource</span> <span class="variable">dataSource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DruidDataSource</span>();</span><br><span class="line"></span><br><span class="line">        dataSource.setDriverClassName(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>);</span><br><span class="line">        dataSource.setUrl(<span class="string">&quot;jdbc:mysql://localhost:3306/fruitdb?&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8&quot;</span>);</span><br><span class="line">        dataSource.setUsername(<span class="string">&quot;root&quot;</span>);</span><br><span class="line">        dataSource.setPassword(<span class="string">&quot;root&quot;</span>);</span><br><span class="line"></span><br><span class="line">        dataSource.setInitialSize(<span class="number">2</span>);</span><br><span class="line">        dataSource.setMaxActive(<span class="number">5</span>);</span><br><span class="line">        dataSource.setMaxWait(<span class="number">5000</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">            <span class="type">Connection</span> <span class="variable">conn1</span> <span class="operator">=</span> dataSource.getConnection();</span><br><span class="line"></span><br><span class="line">            System.out.println(i+<span class="string">&quot; &quot;</span>+conn1);</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p><img src="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/image-20220622185437122.png" alt="image-20220622185437122"></p>
<h4 id="3-2-3-读取配置文件信息创建连接池">3.2.3 读取配置文件信息创建连接池</h4>
<p>在实际开发中，比如数据库url，密码用户等信息都是写在配置文件中，不会直接写在代码中进行硬编码</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zylai.jdbc;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.alibaba.druid.pool.DruidDataSource;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.File;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.io.InputStream;</span><br><span class="line"><span class="keyword">import</span> java.sql.Connection;</span><br><span class="line"><span class="keyword">import</span> java.sql.SQLException;</span><br><span class="line"><span class="keyword">import</span> java.util.Properties;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Zhao YunLai</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2022/06/22/14:13</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 从配置文件中读取信息</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo04Druid</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> SQLException, IOException &#123;</span><br><span class="line"></span><br><span class="line">        <span class="type">Properties</span> <span class="variable">properties</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Properties</span>();</span><br><span class="line">        <span class="type">InputStream</span> <span class="variable">is</span> <span class="operator">=</span> Demo04Druid.class.getClassLoader().getResourceAsStream(<span class="string">&quot;jdbc.properties&quot;</span>);</span><br><span class="line">        properties.load(is);</span><br><span class="line">        <span class="type">DruidDataSource</span> <span class="variable">dataSource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DruidDataSource</span>();</span><br><span class="line"></span><br><span class="line">        dataSource.setDriverClassName(properties.getProperty(<span class="string">&quot;jdbc.driverClassName&quot;</span>));</span><br><span class="line">        dataSource.setUrl(properties.getProperty(<span class="string">&quot;jdbc.url&quot;</span>));</span><br><span class="line">        dataSource.setUsername(properties.getProperty(<span class="string">&quot;jdbc.username&quot;</span>));</span><br><span class="line">        dataSource.setPassword(properties.getProperty(<span class="string">&quot;jdbc.pwd&quot;</span>));</span><br><span class="line"></span><br><span class="line">        dataSource.setInitialSize(Integer.parseInt(properties.getProperty(<span class="string">&quot;druid.initialSize&quot;</span>)));</span><br><span class="line">        dataSource.setMaxActive(Integer.parseInt(properties.getProperty(<span class="string">&quot;druid.maxActive&quot;</span>)));</span><br><span class="line">        dataSource.setMaxWait(Long.parseLong(properties.getProperty(<span class="string">&quot;druid.maxWait&quot;</span>)));</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">            <span class="type">Connection</span> <span class="variable">conn1</span> <span class="operator">=</span> dataSource.getConnection();</span><br><span class="line">            System.out.println(i+<span class="string">&quot; &quot;</span>+conn1);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>配置文件jdbc.properties:</p>
<figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">jdbc.driverClassName</span>=<span class="string">com.mysql.jdbc.Driver</span></span><br><span class="line"><span class="attr">jdbc.url</span>=<span class="string">jdbc:mysql://localhost:3306/fruitdb?&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8</span></span><br><span class="line"><span class="attr">jdbc.username</span>=<span class="string">root</span></span><br><span class="line"><span class="attr">jdbc.pwd</span>=<span class="string">root</span></span><br><span class="line"></span><br><span class="line"><span class="attr">druid.initialSize</span>=<span class="string">2</span></span><br><span class="line"><span class="attr">druid.maxActive</span>=<span class="string">5</span></span><br><span class="line"><span class="attr">druid.maxWait</span>=<span class="string">5000</span></span><br></pre></td></tr></table></figure>
<h4 id="3-2-4-直接通过配置文件建立连接池">3.2.4 直接通过配置文件建立连接池</h4>
<p>通过<code>DruidDataSourceFactory.createDataSource(properties);</code>返回**<code>DataSource</code>接口**，直接通过配置文件建立好了连接池。不过这里对于配置文件的格式有要求。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zylai.jdbc;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.alibaba.druid.pool.DruidDataSource;</span><br><span class="line"><span class="keyword">import</span> com.alibaba.druid.pool.DruidDataSourceFactory;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.sql.DataSource;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.io.InputStream;</span><br><span class="line"><span class="keyword">import</span> java.sql.Connection;</span><br><span class="line"><span class="keyword">import</span> java.sql.SQLException;</span><br><span class="line"><span class="keyword">import</span> java.util.Properties;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: Zhao YunLai</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2022/06/22/14:13</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 直接通过配置文件创建连接池</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo05Druid</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line"></span><br><span class="line">        <span class="type">Properties</span> <span class="variable">properties</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Properties</span>();</span><br><span class="line">        <span class="type">InputStream</span> <span class="variable">is</span> <span class="operator">=</span> Demo05Druid.class.getClassLoader().getResourceAsStream(<span class="string">&quot;jdbc2.properties&quot;</span>);</span><br><span class="line">        properties.load(is);</span><br><span class="line"></span><br><span class="line">        <span class="type">DataSource</span> <span class="variable">dataSource</span> <span class="operator">=</span> DruidDataSourceFactory.createDataSource(properties);</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">            <span class="type">Connection</span> <span class="variable">conn1</span> <span class="operator">=</span> dataSource.getConnection();</span><br><span class="line">            System.out.println(i+<span class="string">&quot; &quot;</span>+conn1);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>配置文件的格式应该一致</p>
<figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">driverClassName</span>=<span class="string">com.mysql.jdbc.Driver</span></span><br><span class="line"><span class="attr">url</span>=<span class="string">jdbc:mysql://localhost:3306/fruitdb?&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8</span></span><br><span class="line"><span class="attr">username</span>=<span class="string">root</span></span><br><span class="line"><span class="attr">password</span>=<span class="string">root</span></span><br><span class="line"></span><br><span class="line"><span class="attr">initialSize</span>=<span class="string">2</span></span><br><span class="line"><span class="attr">maxActive</span>=<span class="string">5</span></span><br><span class="line"><span class="attr">maxWait</span>=<span class="string">5000</span></span><br></pre></td></tr></table></figure>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="https://zhaoyunlai.gitee.io">zylai</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://zhaoyunlai.gitee.io/posts/4bf3ee607b9f/">https://zhaoyunlai.gitee.io/posts/4bf3ee607b9f/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://zhaoyunlai.gitee.io" target="_blank">zylai</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/mysql/">mysql</a></div><div class="post_share"><div class="social-share" data-image="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/jdbcBack.webp" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/posts/9cf7da51c067/"><img class="prev-cover" src="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/mybatis.assets/mybatis-logo.png" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">MyBatis框架</div></div></a></div><div class="next-post pull-right"><a href="/posts/cd56667a4753/"><img class="next-cover" src="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/image-20220502225933236.png" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">【cs231n】详解反向传播</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/posts/9cf7da51c067/" title="MyBatis框架"><img class="cover" src="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/mybatis.assets/mybatis-logo.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-07-23</div><div class="title">MyBatis框架</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="/img/avatar.jpg" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">zylai</div><div class="author-info__description">zylai && 管大虾の克星</div></div><div class="card-info-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">18</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">14</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">11</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/zhaoyunlai"><i class="fab fa-github"></i><span>Follow Me</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/zhaoyunlai" target="_blank" title="Github"><i class="fab fa-github"></i></a><a class="social-icon" href="mailto:zylai0712@163.com" target="_blank" title="Email"><i class="fas fa-envelope"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">This is my blog</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-%E7%AE%80%E4%BB%8B%E5%92%8C%E5%9F%BA%E7%A1%80%E4%BD%BF%E7%94%A8"><span class="toc-text">1 简介和基础使用</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-1-%E7%AE%80%E4%BB%8B"><span class="toc-text">1.1 简介</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-2-%E5%88%9B%E5%BB%BA%E8%BF%9E%E6%8E%A5"><span class="toc-text">1.2 创建连接</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-3-%E6%B7%BB%E5%8A%A0%E6%95%B0%E6%8D%AE"><span class="toc-text">1.3 添加数据</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-4-%E6%9B%B4%E6%96%B0%E5%92%8C%E5%88%A0%E9%99%A4%E6%95%B0%E6%8D%AE"><span class="toc-text">1.4 更新和删除数据</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-5-%E5%A2%9E%E5%88%A0%E6%9B%B4%E6%96%B0%E6%80%BB%E7%BB%93"><span class="toc-text">1.5 增删更新总结</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#1-5-1-%E6%AD%A5%E9%AA%A4%EF%BC%9A"><span class="toc-text">1.5.1 步骤：</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-6-%E6%9F%A5%E8%AF%A2"><span class="toc-text">1.6 查询</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-7-%E6%9F%A5%E8%AF%A2%E6%80%BB%E7%BB%93"><span class="toc-text">1.7 查询总结</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#1-7-1-%E6%9F%A5%E8%AF%A2%E4%B8%8E%E5%A2%9E%E5%88%A0%E6%94%B9%E7%9A%84%E4%B8%8D%E5%90%8C%E4%B9%8B%E5%A4%84%E5%9C%A8%E4%BA%8E%EF%BC%9A"><span class="toc-text">1.7.1 查询与增删改的不同之处在于：</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-7-2-%E6%AD%A5%E9%AA%A4%EF%BC%9A"><span class="toc-text">1.7.2 步骤：</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-8-%E6%89%B9%E5%A4%84%E7%90%86"><span class="toc-text">1.8 批处理</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-%E5%B7%A5%E7%A8%8B"><span class="toc-text">2 工程</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#2-1-%E9%9C%80%E6%B1%82%E6%A6%82%E8%BF%B0%E5%92%8C%E6%95%B4%E4%BD%93%E6%A1%86%E6%9E%B6"><span class="toc-text">2.1 需求概述和整体框架</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-2-%E6%9C%80%E5%88%9D%E7%89%88%E6%9C%AC"><span class="toc-text">2.2 最初版本</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#2-2-1-pojo"><span class="toc-text">2.2.1 pojo</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-2-2-dao"><span class="toc-text">2.2.2 dao</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-2-3-controller"><span class="toc-text">2.2.3 controller</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-2-4-view"><span class="toc-text">2.2.4 view</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-2-5-%E6%9C%80%E5%88%9D%E7%89%88%E6%80%BB%E7%BB%93"><span class="toc-text">2.2.5 最初版总结</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-3-%E6%94%B9%E8%BF%9B%EF%BC%9A%E5%AF%B9%E4%BA%8EFruitDAOImpl%E4%B8%AD%E8%8E%B7%E5%8F%96%E8%BF%9E%E6%8E%A5%E6%93%8D%E4%BD%9C%E4%BB%A5%E5%8F%8A%E9%87%8A%E6%94%BE%E8%B5%84%E6%BA%90%E6%93%8D%E4%BD%9C%E5%81%9A%E4%BA%86%E6%8F%90%E5%8F%96"><span class="toc-text">2.3 改进：对于FruitDAOImpl中获取连接操作以及释放资源操作做了提取</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-4-%E6%94%B9%E8%BF%9B%EF%BC%9A%E8%AE%BE%E7%BD%AE%E6%8A%BD%E8%B1%A1%E7%B1%BB%EF%BC%8C%E5%B9%B6%E6%8A%BD%E5%8F%96%E5%A2%9E%E5%88%A0%E6%94%B9%E6%93%8D%E4%BD%9C"><span class="toc-text">2.4 改进：设置抽象类，并抽取增删改操作</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-5-%E6%94%B9%E8%BF%9B%EF%BC%9A%E6%8A%BD%E5%8F%96%E6%9F%A5%E8%AF%A2%E6%93%8D%E4%BD%9C"><span class="toc-text">2.5 改进：抽取查询操作</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#2-5-1-%E4%BD%BF%E7%94%A8%E6%B3%9B%E5%9E%8B"><span class="toc-text">2.5.1 使用泛型</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-5-2-%E9%80%9A%E8%BF%87%E5%8F%8D%E5%B0%84%E5%BE%97%E5%88%B0%E7%9C%9F%E6%AD%A3%E7%9A%84%E7%B1%BB"><span class="toc-text">2.5.2 通过反射得到真正的类</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-5-3-%E6%9F%A5%E8%AF%A2%E6%96%B9%E6%B3%95"><span class="toc-text">2.5.3 查询方法</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-5-4-%E6%94%B9%E8%BF%9B%E5%90%8E%E7%9A%84%E6%95%B4%E4%B8%AABaseDAO%E7%B1%BB%E4%B8%BA%EF%BC%9A"><span class="toc-text">2.5.4 改进后的整个BaseDAO类为：</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0"><span class="toc-text">3 数据库连接池</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#3-1-%E6%A6%82%E8%BF%B0%E5%92%8C%E4%BC%98%E5%8A%BF"><span class="toc-text">3.1 概述和优势</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#3-1-1-%E5%A5%BD%E5%A4%84%EF%BC%9A"><span class="toc-text">3.1.1 好处：</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-1-2%E8%AF%A6%E7%BB%86%E9%85%8D%E7%BD%AE%E5%8F%82%E6%95%B0%EF%BC%9A"><span class="toc-text">3.1.2详细配置参数：</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-2-%E4%BD%BF%E7%94%A8"><span class="toc-text">3.2 使用</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#3-2-1-%E5%9F%BA%E7%A1%80%E4%BD%BF%E7%94%A8"><span class="toc-text">3.2.1 基础使用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-2-2-%E9%AA%8C%E8%AF%81%E8%BF%9E%E6%8E%A5%E6%B1%A0%E7%9A%84%E9%83%A8%E5%88%86%E5%8F%82%E6%95%B0"><span class="toc-text">3.2.2 验证连接池的部分参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-2-3-%E8%AF%BB%E5%8F%96%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E4%BF%A1%E6%81%AF%E5%88%9B%E5%BB%BA%E8%BF%9E%E6%8E%A5%E6%B1%A0"><span class="toc-text">3.2.3 读取配置文件信息创建连接池</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-2-4-%E7%9B%B4%E6%8E%A5%E9%80%9A%E8%BF%87%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E5%BB%BA%E7%AB%8B%E8%BF%9E%E6%8E%A5%E6%B1%A0"><span class="toc-text">3.2.4 直接通过配置文件建立连接池</span></a></li></ol></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/posts/22ef9dff46af/" title="移动互联网开发技术-第三次实验"><img src="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1.assets/sdnu-background2.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="移动互联网开发技术-第三次实验"/></a><div class="content"><a class="title" href="/posts/22ef9dff46af/" title="移动互联网开发技术-第三次实验">移动互联网开发技术-第三次实验</a><time datetime="2022-10-15T01:43:30.000Z" title="发表于 2022-10-15 09:43:30">2022-10-15</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/85838fb07a8b/" title="学生成长动态追踪系统-学生使用手册"><img src="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1.assets/sdnu-background2.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="学生成长动态追踪系统-学生使用手册"/></a><div class="content"><a class="title" href="/posts/85838fb07a8b/" title="学生成长动态追踪系统-学生使用手册">学生成长动态追踪系统-学生使用手册</a><time datetime="2022-09-25T11:43:30.000Z" title="发表于 2022-09-25 19:43:30">2022-09-25</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/896511b44bb7/" title="学生成长动态追踪系统-家长使用手册"><img src="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1.assets/sdnu-background2.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="学生成长动态追踪系统-家长使用手册"/></a><div class="content"><a class="title" href="/posts/896511b44bb7/" title="学生成长动态追踪系统-家长使用手册">学生成长动态追踪系统-家长使用手册</a><time datetime="2022-09-25T11:43:29.000Z" title="发表于 2022-09-25 19:43:29">2022-09-25</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/78afc3f0ab42/" title="Shiro权限安全框架的使用"><img src="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/shiro.assets/image-20220929162947122.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Shiro权限安全框架的使用"/></a><div class="content"><a class="title" href="/posts/78afc3f0ab42/" title="Shiro权限安全框架的使用">Shiro权限安全框架的使用</a><time datetime="2022-09-18T11:43:29.000Z" title="发表于 2022-09-18 19:43:29">2022-09-18</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/e32230f09e09/" title="学生成长动态追踪系统"><img src="https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1.assets/sdnu-background2.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="学生成长动态追踪系统"/></a><div class="content"><a class="title" href="/posts/e32230f09e09/" title="学生成长动态追踪系统">学生成长动态追踪系统</a><time datetime="2022-08-25T11:43:29.000Z" title="发表于 2022-08-25 19:43:29">2022-08-25</time></div></div></div></div></div></div></main><footer id="footer" style="background-image: url('https://zylai-cloud-pic-1306915061.cos.ap-nanjing.myqcloud.com/images01/jdbcBack.webp')"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2022 By zylai</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.min.js"></script><script src="/js/search/local-search.js"></script><div class="js-pjax"></div><script defer="defer" id="ribbon" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-ribbon.min.js" size="150" alpha="0.6" zIndex="-1" mobile="false" data-click="true"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><!-- hexo injector body_end start --><script data-pjax>function electric_clock_injector_config(){
                var parent_div_git = document.getElementsByClassName('sticky_layout')[0];
                var item_html = '<div class="card-widget card-clock"><div class="card-glass"><div class="card-background"><div class="card-content"><div id="hexo_electric_clock"><img id="card-clock-loading" src="https://cdn.jsdelivr.net/gh/Zfour/Butterfly-clock/clock/images/weather/loading.gif" style="height: 120px; width: 100%;" data-ll-status="loading" class="entered loading"></div></div></div></div></div>';
                console.log('已挂载electric_clock')
                // parent_div_git.innerHTML=item_html+parent_div_git.innerHTML // 无报错，但不影响使用(支持pjax跳转)
                parent_div_git.insertAdjacentHTML("afterbegin",item_html) // 有报错，但不影响使用(支持pjax跳转)
            }if( document.getElementsByClassName('sticky_layout')[0] && (location.pathname ==='/'|| '/' ==='all')){

            electric_clock_injector_config()
        } </script><script src="https://pv.sohu.com/cityjson?ie=utf-8"></script><script data-pjax  src="https://cdn.jsdelivr.net/gh/Zfour/hexo-electric-clock@1.0.6/clock.js"></script><!-- hexo injector body_end end --></body></html>